#include <Windows.h>
#include <memory.h>
#include <cstddef>
#include "speedmeasure.h"

SpeedMeasure::SpeedMeasure()
{
	memset(&m_bwMeter, 0, sizeof(m_bwMeter));
}

void SpeedMeasure::Clear()
{
	memset(&m_bwMeter, 0, sizeof(m_bwMeter));
}

void SpeedMeasure::Add(int nTotal)
{
	if ( m_bwMeter.pHistory && nTotal )
	{
		int tmsNow = ::GetTickCount();

		//LOG(LS_INFO)<<tmsNow<<" : SpeedMeasure, add data, nTotal="<<nTotal<<"\n";
		// If it's less than 1/10 of a second since we last wrote some history information
		if ( tmsNow - m_bwMeter.tLastSlot < METER_MINIMUM )
		{
			// Use the same place in the array as before
			m_bwMeter.pHistory[ m_bwMeter.nPosition ] += nTotal;

		} // It's been more than a tenth of a second since we last recorded a read
		else
		{
			// Store the time and total in a new array slot
			m_bwMeter.nPosition = ( m_bwMeter.nPosition + 1 ) % METER_LENGTH;	// Move to the next position in the array
			m_bwMeter.pTimes[ m_bwMeter.nPosition ] = tmsNow;					// Record the new time
			m_bwMeter.pHistory[ m_bwMeter.nPosition ]	= nTotal;				// Store the bytes read next to it
			m_bwMeter.tLastSlot = tmsNow;										// We just wrote some history information
		}
	}
}

int SpeedMeasure::GetSpeed()
{
	Measure();
	return m_bwMeter.nMeasure;
}

void SpeedMeasure::Measure()
{
	int tCutoff = GetTickCount() - METER_PERIOD*1000;
	// Start counts at zero
	int nTotal  = 0;

	// Loop down the arrays
	for ( std::ptrdiff_t slot = -METER_LENGTH; slot; ++slot )
	{
		// If this record is from the last 2 seconds, add it to the input or output total
		if ( m_bwMeter.pTimes[ METER_LENGTH + slot ] >= tCutoff )
			nTotal += m_bwMeter.pHistory[ METER_LENGTH + slot ];
	}
	// Set nMeasure for input and output as the average bytes read and written per second over the last METER_PERIOD seconds
	m_bwMeter.nMeasure  = nTotal  / METER_PERIOD;
	//LOG(LS_INFO)<< "SpeedMeasure, measure, nTotal="<<nTotal<<"spd = "<<m_bwMeter.nMeasure<<"\n";
}